package com.winding.plugin.swagger.param;

import com.thoughtworks.qdox.model.JavaAnnotation;
import com.thoughtworks.qdox.model.JavaClass;
import com.thoughtworks.qdox.model.JavaMethod;
import com.thoughtworks.qdox.model.JavaParameter;
import com.thoughtworks.qdox.model.impl.DefaultJavaType;
import com.winding.plugin.swagger.utils.SpringAnnotationUtils;
import com.winding.plugin.swagger.utils.TypeUtil;
import io.swagger.converter.ModelConverters;
import io.swagger.models.parameters.Parameter;
import io.swagger.models.properties.*;
import org.apache.commons.lang3.StringUtils;

import java.lang.reflect.Method;
import java.util.List;
import java.util.Map;
import java.util.Optional;

/**
 *
 * @author wind
 * @version 1.0
 * @since 2018/12/5
 */
public abstract class AbstractParamParse {
    protected ModelConverters modelConverters;

    public AbstractParamParse(ModelConverters modelConverters) {
        this.modelConverters = modelConverters;
    }

    public abstract List<Parameter> parseParameter(java.lang.reflect.Parameter parameter, JavaParameter javaParameter, JavaMethod javaMethod,
                                                   Method method, String modelName, Map<String, JavaClass> classJavaClassMap);

    protected boolean isRequire(JavaParameter parameter) {
        JavaAnnotation annotation = SpringAnnotationUtils.getAnnotation(parameter, "RequestParam");
        if (annotation == null) {
            return false;
        }
        return TypeUtil.transBoolean(annotation.getProperty("required"), true);
    }

    protected String getQueryParamName(JavaParameter parameter) {
        Optional<JavaAnnotation> optional = parameter.getAnnotations().stream().filter(v -> v.getType().getSimpleName().equals("RequestParam"))
                .findFirst();
        if (optional.isPresent()) {
            String name = TypeUtil.transString(optional.get().getProperty("name"));
            if (StringUtils.isBlank(name)) {
                return TypeUtil.transString(optional.get().getProperty("value"));
            }
        }
        return null;
    }

    protected String getPathName(JavaParameter parameter) {
        JavaAnnotation annotation = SpringAnnotationUtils.getAnnotation(parameter, "PathVariable");
        if (annotation == null) {
            return null;
        }
        String name = TypeUtil.transString(annotation.getProperty("name"));
        if (StringUtils.isNotBlank(name)) {
            return name;
        } else {
            return TypeUtil.transString(annotation.getProperty("value"));
        }
    }

    protected Property property(JavaParameter parameter) {
        String fullName = parameter.getType().getFullyQualifiedName();
        if (parameter.getType() instanceof DefaultJavaType) {
            DefaultJavaType defaultJavaType = (DefaultJavaType) parameter.getType();
            if (defaultJavaType.isArray()) {
                fullName = "Array";
            }
        }
        switch (fullName) {
            case "int":
            case "java.lang.Integer":
                return new IntegerProperty();
            case "long":
            case "java.lang.Long":
                return new LongProperty();
            case "float":
            case "java.lang.Float":
                return new FloatProperty();
            case "double":
            case "java.lang.Double":
                return new DoubleProperty();
            case "java.lang.String":
                return new StringProperty();
            case "Array":
                return new ArrayProperty();
            default:
                return new StringProperty();
        }
    }

}
